#include <func.h>

int main()
{
    //创建服务器的监听套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(listenfd, -1, "socket");
    printf("listenfd: %d\n", listenfd);


    //设置套接字的属性: 网络地址可以重用(在bind之前进行设置)
    int on = 1;
    int ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    ERROR_CHECK(ret, -1, "setsockopt");

    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    //指定使用的是IPv4的地址类型 AF_INET
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8080);
    serveraddr.sin_addr.s_addr = inet_addr("192.168.30.129");

    //以人类可阅读的方式打印网络地址
    printf("%s:%d\n", 
           inet_ntoa(serveraddr.sin_addr),
           ntohs(serveraddr.sin_port));

    //绑定服务器的网络地址
    ret = bind(listenfd, (const struct sockaddr*)&serveraddr, 
                   sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "bind");

    //监听客户端的到来
    ret = listen(listenfd, 1);
    printf("server is listening.\n");

    while(1){
        struct sockaddr_in clientaddr;
        memset(&clientaddr, 0, sizeof(clientaddr));
        socklen_t len = sizeof(clientaddr);
        printf("len: %d\n", len);
        //通过accept的第二个参数可以获取到客户端的网络地址
        int peerfd = accept(listenfd, 
                            (struct sockaddr*)&clientaddr, &len);
        //peerfd是listenfd的一个分身，主要用来
        //与客户端进行交互
        printf("peerfd: %d\n", peerfd);
        printf("client addr: %s:%d\n", 
               inet_ntoa(clientaddr.sin_addr),
               ntohs(clientaddr.sin_port));

        char buff[100] = "hello,client";

        //sizeof(buff)  求取的数组的长度, 发送的是100个字节
        //ret = send(peerfd, buff, sizeof(buff), 0);
        //对于字符串而言，一般要使用strlen,不能使用sizeof
        sleep(3);// 先休眠3秒钟
        ret = send(peerfd, buff, strlen(buff), 0);
        printf("send %d bytes.\n", ret);

        memset(buff, 0, sizeof(buff));//切记要清空数据
        ret = recv(peerfd, buff, sizeof(buff), 0);
        printf("recv: %s\n", buff);

    }

        //close(peerfd);//关闭套接字
    close(listenfd);

    return 0;
}

